public override void OnPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation)
        {
            if (key.StartsWith("Raven/"))
            {
                return;
            }

            var entityName = metadata.Value <string>(Constants.RavenEntityName) + "/";

            var properties = metadata.Value <RavenJArray>(Constants.EnsureUniqueConstraints);

            if (properties == null || properties.Length <= 0)
            {
                return;
            }

            var oldDoc = Database.Get(key, transactionInformation);

            if (oldDoc == null)
            {
                return;
            }

            foreach (var property in metadata.Value <RavenJArray>(Constants.EnsureUniqueConstraints))
            {
                var constraint = Util.GetConstraint(property);

                var newProp = document[constraint.PropName];

                // Handle Updates in the constraint since it changed
                var prefix = "UniqueConstraints/" + entityName + constraint.PropName + "/";

                var oldProp = oldDoc.DataAsJson[constraint.PropName];

                string[] oldUniqueValues;
                if (!Util.TryGetUniqueValues(oldProp, out oldUniqueValues))
                {
                    continue;
                }

                string[] newUniqueValues;
                if (Util.TryGetUniqueValues(newProp, out newUniqueValues))
                {
                    var join = (from oldValue in oldUniqueValues
                                join newValue in newUniqueValues
                                on oldValue equals newValue
                                select oldValue);

                    if (join.Count() == oldUniqueValues.Count())
                    {
                        continue;
                    }
                }

                foreach (var oldUniqueValue in oldUniqueValues)
                {
                    Database.Delete(prefix + Util.EscapeUniqueValue(oldUniqueValue, constraint.CaseInsensitive), null, transactionInformation);
                }
            }
        }
Esempio n. 2
0
        public override void AfterPut(string key, RavenJObject document, RavenJObject metadata, Etag etag, TransactionInformation transactionInformation)
        {
            if (key.StartsWith("Raven/"))
            {
                return;
            }

            var entityName = metadata.Value <string>(Constants.RavenEntityName) + "/";

            var properties = metadata.Value <RavenJArray>(Constants.EnsureUniqueConstraints);

            if (properties == null || properties.Length <= 0)
            {
                return;
            }

            foreach (var property in properties)
            {
                var constraint = Util.GetConstraint(property);
                var prop       = document[constraint.PropName];

                string[] uniqueValues;
                if (!Util.TryGetUniqueValues(prop, out uniqueValues))
                {
                    continue;
                }

                var prefix = "UniqueConstraints/" + entityName + constraint.PropName + "/";

                foreach (var uniqueValue in uniqueValues)
                {
                    var escapedUniqueValue           = Util.EscapeUniqueValue(uniqueValue, constraint.CaseInsensitive);
                    var uniqueConstraintsDocumentKey = prefix + escapedUniqueValue;
                    var uniqueConstraintsDocument    = Database.Documents.Get(uniqueConstraintsDocumentKey, transactionInformation);

                    if (uniqueConstraintsDocument != null)
                    {
                        uniqueConstraintsDocument = DeepCloneDocument(uniqueConstraintsDocument);
                        ConvertUniqueConstraintsDocumentIfNecessary(uniqueConstraintsDocument, escapedUniqueValue); // backward compatibility
                    }
                    else
                    {
                        uniqueConstraintsDocument = new JsonDocument();
                    }

                    AddConstraintToUniqueConstraintsDocument(uniqueConstraintsDocument, escapedUniqueValue, key);
                    uniqueConstraintsDocument.Metadata[Constants.IsConstraintDocument] = true;

                    Database.Documents.Put(
                        uniqueConstraintsDocumentKey,
                        null,
                        uniqueConstraintsDocument.DataAsJson,
                        uniqueConstraintsDocument.Metadata,
                        transactionInformation);
                }
            }
        }
Esempio n. 3
0
        public override void OnDelete(string key, TransactionInformation transactionInformation)
        {
            if (key.StartsWith("Raven"))
            {
                return;
            }

            var doc = Database.Get(key, transactionInformation);

            if (doc == null)
            {
                return;
            }

            var metadata = doc.Metadata;

            var entityName = metadata.Value <string>(Constants.RavenEntityName) + "/";

            var uniqueConstraits = metadata.Value <RavenJArray>(Constants.EnsureUniqueConstraints);

            if (uniqueConstraits == null)
            {
                return;
            }

            foreach (var property in uniqueConstraits)
            {
                var constraint = Util.GetConstraint(property);
                var prefix     = "UniqueConstraints/" + entityName + constraint.PropName + "/"; // UniqueConstraints/EntityNamePropertyName/
                var prop       = doc.DataAsJson[constraint.PropName];

                string[] uniqueValues;
                if (!Util.TryGetUniqueValues(prop, out uniqueValues))
                {
                    continue;
                }

                foreach (var uniqueValue in uniqueValues)
                {
                    Database.Delete(prefix + Util.EscapeUniqueValue(uniqueValue, constraint.CaseInsensitive), null, transactionInformation);
                }
            }
        }
        public override void AfterPut(string key, RavenJObject document, RavenJObject metadata, Etag etag, TransactionInformation transactionInformation)
        {
            if (key.StartsWith("Raven/"))
            {
                return;
            }

            var entityName = metadata.Value <string>(Constants.RavenEntityName) + "/";

            var properties = metadata.Value <RavenJArray>(Constants.EnsureUniqueConstraints);

            if (properties == null || properties.Length <= 0)
            {
                return;
            }

            foreach (var property in properties)
            {
                var constraint = Util.GetConstraint(property);
                var prop       = document[constraint.PropName];

                string[] uniqueValues;
                if (!Util.TryGetUniqueValues(prop, out uniqueValues))
                {
                    continue;
                }

                var prefix = "UniqueConstraints/" + entityName + constraint.PropName + "/";

                foreach (var uniqueValue in uniqueValues)
                {
                    Database.Put(
                        prefix + Util.EscapeUniqueValue(uniqueValue, constraint.CaseInsensitive),
                        null,
                        RavenJObject.FromObject(new { RelatedId = key }),
                        new RavenJObject {
                        { Constants.IsConstraintDocument, true }
                    },
                        transactionInformation);
                }
            }
        }
Esempio n. 5
0
        public override VetoResult AllowPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation)
        {
            if (key.StartsWith("Raven/"))
            {
                return(VetoResult.Allowed);
            }

            var entityName = metadata.Value <string>(Constants.RavenEntityName);

            if (string.IsNullOrEmpty(entityName))
            {
                return(VetoResult.Allowed);
            }
            entityName += "/";

            var properties = metadata.Value <RavenJArray>(Constants.EnsureUniqueConstraints);

            if (properties == null || properties.Length <= 0)
            {
                return(VetoResult.Allowed);
            }

            var invalidFields = new StringBuilder();

            foreach (var property in properties)
            {
                var constraint = Util.GetConstraint(property);

                var prefix = "UniqueConstraints/" + entityName + constraint.PropName + "/";
                var prop   = document[constraint.PropName];

                string[] uniqueValues;
                if (!Util.TryGetUniqueValues(prop, out uniqueValues))
                {
                    continue;
                }

                foreach (var uniqueValue in uniqueValues)
                {
                    var escapedUniqueValue = Util.EscapeUniqueValue(uniqueValue, constraint.CaseInsensitive);
                    var checkDocKey        = prefix + escapedUniqueValue;
                    var checkDoc           = Database.Documents.Get(checkDocKey, transactionInformation);

                    if (checkDoc == null)
                    {
                        continue;
                    }

                    var checkId = GetRelatedIdFromUniqueConstraintsDocument(checkDoc, escapedUniqueValue);

                    if (!string.IsNullOrEmpty(checkId) && checkId != key)
                    {
                        invalidFields.Append(constraint.PropName + ", ");
                    }
                }
            }

            if (invalidFields.Length > 0)
            {
                invalidFields.Length = invalidFields.Length - 2;
                return(VetoResult.Deny("Ensure unique constraint violated for fields: " + invalidFields));
            }

            return(VetoResult.Allowed);
        }
        public override void OnPut(string key, RavenJObject jsonReplicationDocument, RavenJObject metadata)
        {
            if (key.StartsWith("Raven/"))
            {
                return;
            }

            var entityName = metadata.Value <string>(Constants.RavenEntityName) + "/";

            var properties = metadata.Value <RavenJArray>(Constants.EnsureUniqueConstraints);

            if (properties == null || properties.Length <= 0)
            {
                return;
            }

            var oldDoc = Database.Documents.Get(key);

            if (oldDoc == null)
            {
                return;
            }

            foreach (var property in metadata.Value <RavenJArray>(Constants.EnsureUniqueConstraints))
            {
                var constraint = Util.GetConstraint(property);

                var newProp = jsonReplicationDocument[constraint.PropName];

                // Handle Updates in the constraint since it changed
                var prefix = "UniqueConstraints/" + entityName + constraint.PropName + "/";

                var oldProp = oldDoc.DataAsJson[constraint.PropName];

                string[] oldUniqueValues;
                if (!Util.TryGetUniqueValues(oldProp, out oldUniqueValues))
                {
                    continue;
                }

                string[] newUniqueValues;
                if (Util.TryGetUniqueValues(newProp, out newUniqueValues))
                {
                    var join = (from oldValue in oldUniqueValues
                                join newValue in newUniqueValues
                                on oldValue equals newValue
                                select oldValue);

                    if (join.Count() == oldUniqueValues.Count())
                    {
                        continue;
                    }
                }

                foreach (var oldUniqueValue in oldUniqueValues)
                {
                    var escapedUniqueValue           = Util.EscapeUniqueValue(oldUniqueValue, constraint.CaseInsensitive);
                    var uniqueConstraintsDocumentKey = prefix + escapedUniqueValue;
                    var uniqueConstraintsDocument    = Database.Documents.Get(uniqueConstraintsDocumentKey);

                    if (uniqueConstraintsDocument == null)
                    {
                        continue;
                    }

                    uniqueConstraintsDocument = DeepCloneDocument(uniqueConstraintsDocument);

                    var removed = RemoveConstraintFromUniqueConstraintDocument(uniqueConstraintsDocument, escapedUniqueValue);

                    if (ShouldRemoveUniqueConstraintDocument(uniqueConstraintsDocument))
                    {
                        Database.Documents.Delete(uniqueConstraintsDocumentKey, null);
                    }
                    else if (removed)
                    {
                        Database.Documents.Put(
                            uniqueConstraintsDocumentKey, null,
                            uniqueConstraintsDocument.DataAsJson,
                            uniqueConstraintsDocument.Metadata);
                    }
                }
            }
        }
        public override void OnDelete(string key)
        {
            if (key.StartsWith("Raven"))
            {
                return;
            }

            var doc = Database.Documents.Get(key);

            if (doc == null)
            {
                return;
            }

            var metadata = doc.Metadata;

            var entityName = metadata.Value <string>(Constants.RavenEntityName) + "/";

            var uniqueConstraits = metadata.Value <RavenJArray>(Constants.EnsureUniqueConstraints);

            if (uniqueConstraits == null)
            {
                return;
            }

            foreach (var property in uniqueConstraits)
            {
                var constraint = Util.GetConstraint(property);
                var prefix     = "UniqueConstraints/" + entityName + constraint.PropName + "/"; // UniqueConstraints/EntityNamePropertyName/
                var prop       = doc.DataAsJson[constraint.PropName];

                string[] uniqueValues;
                if (!Util.TryGetUniqueValues(prop, out uniqueValues))
                {
                    continue;
                }

                foreach (var uniqueValue in uniqueValues)
                {
                    var escapedUniqueValue           = Util.EscapeUniqueValue(uniqueValue, constraint.CaseInsensitive);
                    var uniqueConstraintsDocumentKey = prefix + escapedUniqueValue;
                    var uniqueConstraintsDocument    = Database.Documents.Get(uniqueConstraintsDocumentKey);

                    if (uniqueConstraintsDocument == null)
                    {
                        continue;
                    }

                    var removed = RemoveConstraintFromUniqueConstraintDocument(uniqueConstraintsDocument, escapedUniqueValue);

                    if (ShouldRemoveUniqueConstraintDocument(uniqueConstraintsDocument))
                    {
                        Database.Documents.Delete(uniqueConstraintsDocumentKey, null);
                    }
                    else if (removed)
                    {
                        Database.Documents.Put(
                            uniqueConstraintsDocumentKey,
                            null,
                            uniqueConstraintsDocument.DataAsJson,
                            uniqueConstraintsDocument.Metadata);
                    }
                }
            }
        }